package org.sgx.gwtsjcl.client;

import com.google.gwt.core.client.JavaScriptObject;

/**
 * Arrays of bits, encoded as arrays of Numbers.
 * 
 * @see http://bitwiseshiftleft.github.com/sjcl/doc/symbols/sjcl.bitArray.html
 * 
 *      <p>
 *      These objects are the currency accepted by SJCL's crypto functions.
 *      </p>
 * 
 *      <p>
 *      Most of our crypto primitives operate on arrays of 4-byte words internally, but many of them can take arguments that are not a multiple of 4 bytes. This library encodes
 *      arrays of bits (whose size need not be a multiple of 8 bits) as arrays of 32-bit words. The bits are packed, big-endian, into an array of words, 32 bits at a time. Since
 *      the words are double-precision floating point numbers, they fit some extra data. We use this (in a private, possibly-changing manner) to encode the number of bits actually
 *      present in the last word of the array.
 *      </p>
 * 
 *      <p>
 *      Because bitwise ops clear this out-of-band data, these arrays can be passed to ciphers like AES which want arrays of words.
 *      </p>
 * 
 * 
 * @author sg
 * 
 */
public class BitArray extends JavaScriptObject {
	protected BitArray() {
	}

	/**
	 * Find the length of an array of bits.
	 * 
	 * @param a
	 *            The array.
	 * @return The length of a, in bits.
	 */
	public native final int bitLength(BitArrayType a)/*-{
		return this.bitLength(a);
	}-*/;

	/**
	 * Array slices in units of bits.
	 * 
	 * @param The
	 *            array to slice.
	 * @param bstart
	 *            The offset to the start of the slice, in bits.
	 * @param bend
	 *            The offset to the end of the slice, in bits. If this is undefined, slice until the end of the array.
	 * @return The requested slice.
	 */
	public native final BitArrayType bitSlice(BitArrayType The, int bstart, int bend)/*-{
		return this.bitSlice(The, bstart, bend);
	}-*/;

	/**
	 * 
	 * @param a
	 *            The array.
	 * @param len
	 *            The length to truncate to, in bits.
	 * @return A new array, truncated to len bits.
	 */
	public native final BitArrayType clamp(BitArrayType a, int len)/*-{
		return this.clamp(a, len);
	}-*/;

	/**
	 * Concatenate two bit arrays.
	 * 
	 * @param a1
	 *            The first array.
	 * @param a2
	 *            The second array.
	 * @return The concatenation of a1 and a2.
	 */
	public native final BitArrayType concat(BitArrayType a1, BitArrayType a2)/*-{
		return this.concat(a1, a2);
	}-*/;

	/**
	 * Compare two arrays for equality in a predictable amount of time.
	 * 
	 * @param a
	 *            The first array.
	 * @param b
	 *            The second array.
	 * @return true if a == b; false otherwise.
	 */
	public native final boolean equal(BitArrayType a, BitArrayType b)/*-{
		return this.equal(a, b);
	}-*/;

	// TODO: others: getPartial, partial.
}
